package utils

import (
	"bytes"
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"errors"
	"os"
)

// GenRsaKey RSA公钥私钥产生
// bits 密钥位宽
// privatePath 私钥文件保存路径
// publicPath 公钥文件保存路径
func GenRsaKey(bits int, privatePath, publicPath string) error {
	// 生成私钥文件
	privateStr, publicStr, err := GenRsaKeyStr(bits)

	if err != nil {
		err = errors.New("GenRsaKeyStr error: " + err.Error())
		return err
	}

	file, err := os.Create(privatePath) //"private.pem")
	if err != nil {
		return errors.New("Create privatePath error: " + err.Error())
	}
	ok, err := Write(file, privateStr)
	if !ok {
		return errors.New("Write privateStr error: " + err.Error())
	}

	file, err = os.Create(publicPath) //"public.pem")
	if err != nil {
		return errors.New("Create publicPath error: " + err.Error())
	}
	ok, err = Write(file, publicStr)
	if !ok {
		return errors.New("Write publicStr error: " + err.Error())
	}
	return nil
}

// GenRsaKeyStr RSA公钥私钥产生
func GenRsaKeyStr(bits int) (publicKeyStr, privateKeyStr string, err error) {
	// 生成私钥文件
	privateKey, err := rsa.GenerateKey(rand.Reader, bits)
	if err != nil {
		return
	}
	derStream := x509.MarshalPKCS1PrivateKey(privateKey)
	block := &pem.Block{
		Type:  "RSA PRIVATE KEY",
		Bytes: derStream,
	}
	bufferPrivate := new(bytes.Buffer)
	err = pem.Encode(bufferPrivate, block)
	if err != nil {
		return
	}
	privateKeyStr = bufferPrivate.String()
	// 生成公钥文件
	publicKey := &privateKey.PublicKey
	derPkix, err := x509.MarshalPKIXPublicKey(publicKey)
	if err != nil {
		return
	}
	block = &pem.Block{
		Type:  "PUBLIC KEY",
		Bytes: derPkix,
	}
	bufferPublic := new(bytes.Buffer)
	err = pem.Encode(bufferPublic, block)
	if err != nil {
		return
	}
	publicKeyStr = bufferPublic.String()
	return

}

// CheckRsa 测试Rsa密钥是否有效
func CheckRsa(privateStr, publicStr string) bool {
	return false
}

// RSAPubDecrypt RSA公钥解密
// cipherText  密文
// publicStr  公钥
func RSAPubDecrypt(cipherText []byte, publicStr string) []byte {

	return nil
}

// RSAPubEncrypt RSA公钥加密
// plainText 要加密的数据
// path 公钥匙文件地址
func RSAPubEncrypt(plainText []byte, path string) []byte {
	//打开文件
	buf, err := Read(path)
	if err != nil {
		panic(err)
	}
	//pem解码
	block, _ := pem.Decode(buf)
	//x509解码

	publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		panic(err)
	}
	//类型断言
	publicKey := publicKeyInterface.(*rsa.PublicKey)
	//对明文进行加密
	cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, plainText)
	if err != nil {
		panic(err)
	}
	//返回密文
	return cipherText
}

// RSAPrivEncrypt RSA私钥加密
// plainText 明文
// privateStr 私钥
func RSAPrivEncrypt(plainText []byte, privateStr string) []byte {

	return nil
}

// RSAPrivDecrypt RSA私钥解密
// cipherText 需要解密的byte数据
// path 私钥文件路径
func RSAPrivDecrypt(cipherText []byte, path string) []byte {
	//打开文件
	buf, err := Read(path)
	if err != nil {
		panic(err)
	}
	//pem解码
	block, _ := pem.Decode(buf)
	//X509解码
	privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		panic(err)
	}
	//对密文进行解密
	plainText, _ := rsa.DecryptPKCS1v15(rand.Reader, privateKey, cipherText)
	//返回明文
	return plainText
}
